package com.hk.blog.service.impl;

import com.hk.blog.domain.Menu;
import com.hk.blog.repository.jpa.MenuRepository;
import com.hk.blog.service.MenuService;
import com.hk.commons.JsonResult;
import com.hk.commons.util.Constants;
import com.hk.commons.util.ObjectUtils;
import com.hk.core.data.jpa.repository.BaseJpaRepository;
import com.hk.core.service.exception.ServiceException;
import com.hk.core.service.jpa.impl.JpaServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.Objects;
import java.util.function.Function;

@Service
@RequiredArgsConstructor
public class MenuServiceImpl extends JpaServiceImpl<Menu, Long> implements MenuService {

    private final MenuRepository menuRepository;

    @Override
    protected BaseJpaRepository<Menu, Long> getBaseRepository() {
        return menuRepository;
    }

    @Override
    protected ExampleMatcher ofExampleMatcher() {
        return super.ofExampleMatcher()
                .withMatcher("parentId", ExampleMatcher.GenericPropertyMatchers.exact())
                .withMatcher("menuName", ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("path", ExampleMatcher.GenericPropertyMatchers.contains());
    }

    @Override
    @Transactional
    public Menu insert(Menu menu, Function<Menu, Menu> function) {
        menu = function.apply(menu);
        if (menu.getMeta() == null) {
            menu.setMeta(new com.hk.core.authentication.api.menus.Menu.Meta().setTitle(menu.getMenuName()));
        }
        menu.setParentId(ObjectUtils.defaultIfNull(menu.getParentId(), Constants.DEFAULT_VALUE_LONG));
        if (!Objects.equals(menu.getParentId(), Constants.DEFAULT_VALUE_LONG)) {
            menu.getMeta().setOpenKeys(Collections.singleton(menu.getParentId()));
        }
        menu.setSortBy(ObjectUtils.defaultIfNull(menu.getSortBy(), Integer.MAX_VALUE));
        return menuRepository.save(menu);
    }

    @Override
    public Menu updateById(Menu menu, Function<Menu, Menu> function) {
        menu = function.apply(menu);
        if (menu.getMeta() == null) {
            menu.setMeta(new com.hk.core.authentication.api.menus.Menu.Meta().setTitle(menu.getMenuName()));
        }
        menu.setParentId(ObjectUtils.defaultIfNull(menu.getParentId(), Constants.DEFAULT_VALUE_LONG));
        if (!Objects.equals(menu.getParentId(), Constants.DEFAULT_VALUE_LONG)) {
            menu.getMeta().setOpenKeys(Collections.singleton(menu.getParentId()));
        }
        menu.setSortBy(ObjectUtils.defaultIfNull(menu.getSortBy(), Integer.MAX_VALUE));
        return menuRepository.save(menu);
    }

    @Override
    public void deleteById(Long id) {
        if (menuRepository.countByParentId(id) > 0) {
            throw new ServiceException(JsonResult.failure("存在子级不能删除"));
        }
        menuRepository.deleteById(id);
    }
}
